<?php
class Contest_Paginator extends Zend_Paginator{

	protected $_table;

	/**
     * Factory.
     *
     * @param  mixed $data
     * @param  string $adapter
     * @param  array $prefixPaths
     * @return Zend_Paginator
     */
    public static function factory($data, $adapter = self::INTERNAL_ADAPTER,
                                   array $prefixPaths = null)
    {
        if ($data instanceof Zend_Paginator_AdapterAggregate) {
            return new self($data->getPaginatorAdapter());
        } else {
            if ($adapter == self::INTERNAL_ADAPTER) {
                if (is_array($data)) {
                    $adapter = 'Array';
                } else if ($data instanceof Zend_Db_Table_Select) {
                    $adapter = 'DbTableSelect';
                } else if ($data instanceof Zend_Db_Select) {
                    $adapter = 'DbSelect';
                } else if ($data instanceof Iterator) {
                    $adapter = 'Iterator';
                } else if (is_integer($data)) {
                    $adapter = 'Null';
                } else {
                    $type = (is_object($data)) ? get_class($data) : gettype($data);

                    /**
                     * @see Zend_Paginator_Exception
                     */
                    require_once 'Zend/Paginator/Exception.php';

                    throw new Zend_Paginator_Exception('No adapter for type ' . $type);
                }
            }

            $pluginLoader = self::getAdapterLoader();

            if (null !== $prefixPaths) {
                foreach ($prefixPaths as $prefix => $path) {
                    $pluginLoader->addPrefixPath($prefix, $path);
                }
            }

            $adapterClassName = $pluginLoader->load($adapter);

			Zend_Paginator::setCache(YouNet_Util::getMemCache());
            $paginator = new self(new $adapterClassName($data));
			$paginator->setCacheEnabled(true);
			if( $data instanceof Zend_Db_Table_Select )
			{
				$paginator->_table = $data->getTable();
			}
			return $paginator;
        }
    }

	public function getItemsByPage($pageNumber)
    {
        $pageNumber = $this->normalizePageNumber($pageNumber);
		$key		= $this->_getCacheId($pageNumber);
        if ($this->_cacheEnabled())
		{
			$data = self::$_cache->load($key);
			if ($data !== false)
			{
				$id_contest = isset($data[0]['id_contest'])?$data[0]['id_contest']:0;
				if( $id_contest )
				{
					$contest_cache	= self::$_cache->load(Core_Cache_IKeys::MEMCACHE_CONTEST_CONTROL . $id_contest);
					if( $contest_cache !== false)
					{
						if( in_array($key, $contest_cache) )
						{
							$arrItems	= $data;
							$arrModel	= array();
							$table		= new $this->_table;
							foreach($arrItems as $item)
							{
								$itemData	= self::$_cache->load(Core_Cache_IKeys::MEMCACHE_MODEL_ENTRY.$item['id']);
								if( $itemData === false)
								{
									$arrModel[] = $table->createRow($item);
								}
								else
								{
									$itemData['fullname']	= $item['fullname'];
									$itemData['link']		= $item['link'];
									$arrModel[] = $table->createRow($itemData);
								}
							}
							$data = new ArrayIterator($arrModel);
							return $data;
						}
					}
				}
			}
        }

        $offset = ($pageNumber - 1) * $this->getItemCountPerPage();

        $items = $this->_adapter->getItems($offset, $this->getItemCountPerPage());

        $filter = $this->getFilter();

        if ($filter !== null) {
            $items = $filter->filter($items);
        }

        if (!$items instanceof Traversable) {
            $items = new ArrayIterator($items);
        }

        if ($this->_cacheEnabled()) {
			$arrItems = array();
			foreach($items as $item)
			{
				$arrItem		= $item->toArray();
				$arrItems[]		= $arrItem;
				if( !self::$_cache->test(Core_Cache_IKeys::MEMCACHE_MODEL_ENTRY.$item->id) )
				{
					self::$_cache->save(
						$arrItem,
						Core_Cache_IKeys::MEMCACHE_MODEL_ENTRY.$item->id,
						array($this->_getCacheInternalId()),
                        3600
					);
				}
			}
			$items->rewind();
            self::$_cache->save($arrItems, $key, array($this->_getCacheInternalId()),3600);
			if( !empty($item) )
			{
				$contest_cache	= self::$_cache->load(Core_Cache_IKeys::MEMCACHE_CONTEST_CONTROL . $item->id_contest);
				if( $contest_cache === false){
					$contest_cache = array();
				}
				if( !in_array($key,$contest_cache) )
				{
					$contest_cache[] = $key;
					self::$_cache->save(
						$contest_cache,
						Core_Cache_IKeys::MEMCACHE_CONTEST_CONTROL . $item->id_contest,
						array($this->_getCacheInternalId()),
						2592000//30days
					);
				}
			}
        }

        return $items;
    }
}